import wx
import SimpleCalendar as sc
from wx.lib.pubsub import setuparg1
from wx.lib.pubsub import pub

from SimpleDialogs import DialogAddItem
import SimplePanels
import datetime
from ModelBaseList import ListItem
from ModelTodo import ModelTodo
from DataManager import DataManager
import copy

class ViewTodoCalendar(wx.Panel):
    #to tell you the true. This class is badly designed
    #because control and view are not sperated
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.init_widgets()
        self.init_control()
        self.init_data()
        
    def init_widgets(self):
        #1. a day select calendar
        #2. my SimpleCalendarCtrl
        #nothing more
        #guess the gui will look quite empty on the first line
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.pk = wx.DatePickerCtrl(
            self, size=wx.Size(100, 30),
            style=wx.DP_DROPDOWN | wx.DP_ALLOWNONE | wx.DP_SHOWCENTURY)
        self.cc = sc.SimpleCalendarCtrl(self)
        self.sizer.Add(self.pk, 0, wx.EXPAND)
        self.sizer.Add(self.cc, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        

    def init_control(self):
        self.Bind(sc.EVT_SELECTED, self.on_new_selection, self.cc)
        self.Bind(wx.EVT_DATE_CHANGED, self.on_ref_change, self.pk)
        pub.subscribe(self.on_add_new_item, ModelTodo.M_ADD_ITEM)
        pub.subscribe(self.on_delete_item, ModelTodo.M_DEL_ITEM)
        pub.subscribe(self.on_time_mode_change, SimplePanels.PanelTodo.M_TIME_CHANGE)
        pub.subscribe(self.on_refresh, ModelTodo.M_REFRESH_ITEM)
        
    def init_data(self):
        self.mode = SimplePanels.PANEL_VIEW_TIME_WEEK
        self.ref = datetime.date.today()
        #load all shit into that list
        self.load()
    
    def on_ref_change(self, evt):
        #this will be called when user seleceted another day
        pk = self.pk
        dt = pk.GetValue()
        if not dt.IsValid():
            return
        y = dt.Year
        m = dt.Month+1
        d = dt.Day
        self.cc.change_mode_ref(self.mode, datetime.date(y,m,d))

    def on_time_mode_change(self, m):
        #NOTE: this should be a subscribed event
        #this deal with the case when user choosed another mode among
        #day month week
        if m.data == SimplePanels.PANEL_VIEW_TIME_ALL:
            #lucky
            return
        self.mode = m.data
        if m.data == SimplePanels.PANEL_VIEW_TIME_DAY:
            self.cc.change_mode_ref(sc.MODE_DAY, self.ref)
        elif m.data == SimplePanels.PANEL_VIEW_TIME_WEEK:
            self.cc.change_mode_ref(sc.MODE_WEEK, self.ref)        
        elif m.data == SimplePanels.PANEL_VIEW_TIME_MONTH:
            self.cc.change_mode_ref(sc.MODE_MONTH, self.ref)

    def on_refresh(self, m):
        self.cc.remove_all()
        self.load()
        
    def on_new_selection(self, evt):
        #this deal with selection event
        ret = []
        tmp = ListItem.get_template()
        #d is a date(not datetime) object
        d, s, e = evt.mydata
        #be careful, this data is a reference to something indside that widget
        start = datetime.datetime.combine(d, datetime.time(s[0], s[1]))
        tmp[1] = start
        # a new datetime object
        end = datetime.datetime.combine(d, datetime.time(e[0], e[1]))
        tmp[2] = end
        dialog = DialogAddItem(ret, DialogAddItem.TODO_MODE, tmp)
        r = dialog.ShowModal()
        dialog.Destroy()
        if r != 0:
            #cancel case: do nothing here
            pass
        else:
            i = DataManager.todolist.build_append(ret)

    def on_add_new_item(self, m):
        #message from model
        #d is a ListItem object
        #these code are very confusing
        d = m.data
        start_dt = d.start
        end_dt = d.end
        if start_dt.day != start_dt.day:
            print("wow! a cross day job, I do not know how to handle it!")
        #this really is only a day number
        #day_num = start_dt.day
        #SimpleCalendar accept hour:minute in a float format
        start = start_dt.hour + start_dt.minute/60.0
        end = end_dt.hour + end_dt.minute/60.0
        self.cc.add(start_dt.date(), start, end, d.title, sync=1)

    def on_delete_item(self, m):
        #an item is deleted
        #d is a ListItem object
        #these code are very confusing, for I made up some
        #very ambigious variable names
        d = m.data
        if d.start.day != d.end.day:
            print("wow! a cross day job, I do not know how to handle it!")
        day = d.start
        start = day.hour + day.minute/60.0
        self.cc.remove(day.date(), start, sync=1)

    def load(self):
        #used in intialization
        for i in DataManager.todolist.get():
            s = i.start
            e = i.end
            start = s.hour + s.minute/60.0
            end = e.hour + e.minute/60.0
            self.cc.add(i.start.date(), start, end, i.title, sync=0)
        #sync at last
        self.cc.update()
